package com.example.jimuyutabletcontrol.activity;

import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.mapapi.model.LatLng;
import com.example.jimuyutabletcontrol.R;
import com.example.jimuyutabletcontrol.network.udp.UdpMessageHandle;
import com.example.jimuyutabletcontrol.network.udp.UdpMessageType;
import com.example.jimuyutabletcontrol.network.udp.UdpSocket;
import com.example.jimuyutabletcontrol.recyclerlistener.OnActivityTouchListener;
import com.example.jimuyutabletcontrol.recyclerlistener.RecyclerTouchListener;
import com.example.jimuyutabletcontrol.recyclerlistener.RowModel;
import com.example.jimuyutabletcontrol.utils.Constants;
import com.marcoscg.headerdialog.HeaderDialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class SailTaskActivity extends AppCompatActivity implements
        RecyclerTouchListener.RecyclerTouchListenerHelper, Toolbar.OnMenuItemClickListener, View.OnClickListener {
    RecyclerView mRecyclerView;
    MainAdapter mAdapter;
    private RecyclerTouchListener onTouchListener;
    private OnActivityTouchListener touchListener;
    /*
    private View view;
    private AlertDialog alertDialog;
    private EditText editSpeed;
    private EditText editDepth;
    private EditText editTime;
    */

    private HeaderDialog headerDialog;

    private int mPosition = -1;
    public Boolean mappingRecord;

    private static SailTaskActivity self;
    private UdpMessageHandle handle;

    public static SailTaskActivity getInstance() {
        return self;
    }

    private Point[] pentagonVertices;
    private Button[] buttons;
    private int width;
    private int radius;
    private int startPositionX;
    private int startPositionY;
    private int whichAnimation;
    private int NUM_OF_SIDES;
    private int[] enterDelay = {80, 120, 160, 40, 0, 200, 240};
    private int[] exitDelay = {80, 40, 0, 120, 160, 200, 240};
    private String[] content = {"手动遥控", "信息查询"};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sailtaskinterface_activity);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbarsail);
        toolbar.setTitle("AUV任务设置执行");
        setSupportActionBar(toolbar);

        self = this;
        if (toolbar != null) {
            toolbar.setOnMenuItemClickListener(this);
        }

        mRecyclerView = findViewById(R.id.recyclerView);
        mAdapter = new MainAdapter(this, getData(null));
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        /*
        view = getLayoutInflater().inflate(R.layout.sailtask_straight_dialog, null);
        editTime = view.findViewById(R.id.input1);
        editSpeed = view.findViewById(R.id.input2);
        editDepth = view.findViewById(R.id.input3);
        */

        onTouchListener = new RecyclerTouchListener(this, mRecyclerView);
        Constants.auvDots = new HashMap<String, ArrayList<LatLng>>();
        Constants.auvColors = new HashMap<>();

        setListener();
        prepareFloatButton();
    }

    private void prepareFloatButton() {
        startPositionX = 0;
        startPositionY = 0;
        whichAnimation = 0;
        NUM_OF_SIDES = 2;
        width = 200;
        radius = 200;

        calculatePentagonVertices(radius, 11);
    }

    private void calculatePentagonVertices(int radius, int rotation) {

        pentagonVertices = new Point[NUM_OF_SIDES];

        /**
         * Calculating the center of pentagon
         */
        Display display = getWindowManager().getDefaultDisplay();
        int centerX = display.getWidth() / 2;
        int centerY = display.getHeight() / 2;

        /**
         * Calculating the coordinates of vertices of pentagon
         */
        for (int i = 0; i < NUM_OF_SIDES; i++) {
            pentagonVertices[i] = new Point((int) (radius * Math.cos(rotation + i * 2 * Math.PI / NUM_OF_SIDES)) + centerX,
                    (int) (radius * Math.sin(rotation + i * 2 * Math.PI / NUM_OF_SIDES)) + centerY - 100);
        }

        buttons = new Button[pentagonVertices.length];

        for (int i = 0; i < buttons.length; i++) {
            //Adding button at (0,0) coordinates and setting their visibility to zero
            buttons[i] = new Button(SailTaskActivity.this);
            buttons[i].setLayoutParams(new RelativeLayout.LayoutParams(100, 100));
            buttons[i].setX(0);
            buttons[i].setY(0);
            buttons[i].setTag(i);
            buttons[i].setOnClickListener(this);
            buttons[i].setVisibility(View.INVISIBLE);
            buttons[i].setBackgroundResource(R.drawable.circular_background);
            buttons[i].setTextColor(Color.DKGRAY);
            buttons[i].setText(content[i]);
            buttons[i].setTextSize(14);
            /**
             * Adding those buttons in acitvities layout
             */
            ((RelativeLayout) findViewById(R.id.main_sail)).addView(buttons[i]);
        }
    }

    private void playEnterAnimation(final Button button, int position) {

        /**
         * Animator that animates buttons x and y position simultaneously with size
         */
        AnimatorSet buttonAnimator = new AnimatorSet();

        /**
         * ValueAnimator to update x position of a button
         */
        ValueAnimator buttonAnimatorX = ValueAnimator.ofFloat(startPositionX + button.getLayoutParams().width / 2,
                pentagonVertices[position].x);
        buttonAnimatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setX((float) animation.getAnimatedValue() - button.getLayoutParams().width / 2);
                button.requestLayout();
            }
        });
        buttonAnimatorX.setDuration(300);

        /**
         * ValueAnimator to update y position of a button
         */
        ValueAnimator buttonAnimatorY = ValueAnimator.ofFloat(startPositionY + 5,
                pentagonVertices[position].y);
        buttonAnimatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setY((float) animation.getAnimatedValue());
                button.requestLayout();
            }
        });
        buttonAnimatorY.setDuration(300);

        /**
         * This will increase the size of button
         */
        ValueAnimator buttonSizeAnimator = ValueAnimator.ofInt(5, width);
        buttonSizeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.getLayoutParams().width = (int) animation.getAnimatedValue();
                button.getLayoutParams().height = (int) animation.getAnimatedValue();
                button.requestLayout();
            }
        });
        buttonSizeAnimator.setDuration(300);

        /**
         * Add both x and y position update animation in
         *  animator set
         */
        buttonAnimator.play(buttonAnimatorX).with(buttonAnimatorY).with(buttonSizeAnimator);
        buttonAnimator.setStartDelay(enterDelay[position]);
        buttonAnimator.start();
    }

    private void playExitAnimation(final Button button, int position) {

        /**
         * Animator that animates buttons x and y position simultaneously with size
         */
        AnimatorSet buttonAnimator = new AnimatorSet();

        /**
         * ValueAnimator to update x position of a button
         */
        ValueAnimator buttonAnimatorX = ValueAnimator.ofFloat(pentagonVertices[position].x - button.getLayoutParams().width / 2,
                startPositionX);
        buttonAnimatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setX((float) animation.getAnimatedValue());
                button.requestLayout();
            }
        });
        buttonAnimatorX.setDuration(300);

        /**
         * ValueAnimator to update y position of a button
         */
        ValueAnimator buttonAnimatorY = ValueAnimator.ofFloat(pentagonVertices[position].y,
                startPositionY + 5);
        buttonAnimatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setY((float) animation.getAnimatedValue());
                button.requestLayout();
            }
        });
        buttonAnimatorY.setDuration(300);

        /**
         * This will decrease the size of button
         */
        ValueAnimator buttonSizeAnimator = ValueAnimator.ofInt(width, 5);
        buttonSizeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.getLayoutParams().width = (int) animation.getAnimatedValue();
                button.getLayoutParams().height = (int) animation.getAnimatedValue();
                button.requestLayout();
            }
        });
        buttonSizeAnimator.setDuration(300);

        /**
         * Add both x and y position update animation in
         *  animator set
         */
        buttonAnimator.play(buttonAnimatorX).with(buttonAnimatorY).with(buttonSizeAnimator);
        buttonAnimator.setStartDelay(exitDelay[position]);
        buttonAnimator.start();
    }

    @Override
    public void onClick(View view) {
        Intent intent = null;
        switch ((int) view.getTag()) {
            case 0:
                intent = new Intent(SailTaskActivity.this, ControlActivity.class);
                startActivity(intent);
                finish();
                break;
            case 1:
                intent = new Intent(SailTaskActivity.this, OnlineAUVActivity.class);
                startActivity(intent);
                finish();
                break;
        }
    }

    private void setListener() {
        onTouchListener
                .setIndependentViews(R.id.rowButton)
                .setViewsToFade(R.id.rowButton)
                .setClickable(new RecyclerTouchListener.OnRowClickListener() {
                    @Override
                    public void onRowClicked(int position) {
                        Log.e("onTouchListener","onRowClicked");
                        System.out.println("click");
                    }

                    @Override //button
                    public void onIndependentViewClicked(int independentViewID, int position) {
                        Log.e("onTouchListener","onIndependentViewClicked");
                        String check1 = mAdapter.modelList.get(position).getMainText();
                        String check2 = mAdapter.modelList.get(position).getSubText();
                        if (!check1.contains("AUV") && !check2.contains("AUV")) {
                            if (check2.contains("afa")) {
                                if (check2.split(",").length != 9) {
                                    toastMsg("请输入正确的参数");
                                    return;
                                }
                            }
                            String order = "B" + check1 + check2;
                            UdpSocket.getInstance().sendMessage(order);
                            System.out.println("order: " + order);
                        } else {
                            toastMsg("请刷新加载在线AUV并且请输入正确的参数");
                        }
                    }
                })
                .setLongClickable(true, new RecyclerTouchListener.OnRowLongClickListener() {
                    @Override
                    public void onRowLongClicked(int position) {
                        Log.e("onTouchListener","onRowLongClicked");
                        Intent intent = new Intent(SailTaskActivity.this, DotActivity.class);
                        startActivity(intent);
                    }
                })
                .setSwipeOptionViews(R.id.straight, R.id.navigation, R.id.stop)
                .setSwipeable(R.id.rowFG, R.id.rowBG, new RecyclerTouchListener.OnSwipeOptionsClickListener() {
                    @Override
                    public void onSwipeOptionClicked(int viewID, int position) {
                        if (viewID == R.id.straight) {
                            mPosition = position;
                            headerDialog = null;
                            createHeaderDialog();
                            headerDialog.show();
                        } else if (viewID == R.id.navigation) {
                            mPosition = position;
                            headerDialog = null;
                            createTestDialog();
                            headerDialog.show();
                        } else if (viewID == R.id.stop) {
                            mAdapter.modelList.get(position).setSubText("stop");
                            mRecyclerView.setAdapter(mAdapter);
                        }
                    }
                });
        handle = new UdpMessageHandle(UdpMessageType.IMEI, this::updateListDataToAdapter);
        UdpSocket.getInstance().setMessageCallback(handle);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mappingRecord = false;
        mRecyclerView.addOnItemTouchListener(onTouchListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        self = null;
        if (Constants.auvDots != null) {
            Constants.auvDots.clear();
            Constants.auvDots = null;
        }
        if (Constants.auvColors != null) {
            Constants.auvColors.clear();
            Constants.auvColors = null;
        }
        if (null != handle) {
            UdpSocket.getInstance().removeMessageCallback(handle);
            handle = null;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mRecyclerView.removeOnItemTouchListener(onTouchListener);
    }

    private List<RowModel> getData(String[] contents) {
        if (contents == null) {
            List<RowModel> list = new ArrayList<>();
            list.add(new RowModel("无在线AUV,点击右上角图标刷新", "左滑添加AUV任务"));
            return list;
        } else {
            List<RowModel> list = new ArrayList<>();
            int length = contents.length;
            for (int i = 1; i < length; i++) {
                list.add(new RowModel(contents[i], "左滑添加AUV任务"));
            }
            return list;
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (touchListener != null) touchListener.getTouchCoordinates(ev);
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public void setOnActivityTouchListener(OnActivityTouchListener listener) {
        this.touchListener = listener;
    }

    private class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainViewHolder> {
        LayoutInflater inflater;
        List<RowModel> modelList;

        public MainAdapter(Context context, List<RowModel> list) {
            inflater = LayoutInflater.from(context);
            modelList = new ArrayList<>(list);
        }

        @Override
        public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = inflater.inflate(R.layout.sailtaskinterface_recycler_row, parent, false);
            return new MainViewHolder(view);
        }

        @Override
        public void onBindViewHolder(MainViewHolder holder, int position) {
            holder.bindData(modelList.get(position));
        }

        @Override
        public int getItemCount() {
            return modelList.size();
        }

        class MainViewHolder extends RecyclerView.ViewHolder {

            TextView mainText, subText;

            public MainViewHolder(View itemView) {
                super(itemView);
                mainText = (TextView) itemView.findViewById(R.id.mainText);
                subText = (TextView) itemView.findViewById(R.id.subText);
            }

            public void bindData(RowModel rowModel) {
                mainText.setText(rowModel.getMainText());
                subText.setText(rowModel.getSubText());
            }
        }
    }

    private void toastMsg(final String msg) {
        runOnUiThread(() -> Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show());
    }

    private void updateListDataToAdapter(String message) {
        runOnUiThread(()->{
            if (mAdapter != null) {
                String[] contents = message.split(",");
                if (contents.length > 1) {
                    mAdapter = new MainAdapter(this, getData(contents));
                    mRecyclerView.setAdapter(mAdapter);
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.sailtaskinterface_menu, menu);
        return true;
    }

    @Override
    public boolean onMenuItemClick(MenuItem menuItem) {
        if (menuItem.getItemId() == R.id.action_download) {

            if (Constants.auvDots != null) {
                Constants.auvDots.clear();
                Constants.auvDots = null;
            }

            if (Constants.auvColors != null) {
                Constants.auvColors.clear();
                Constants.auvColors = null;
            }

            Constants.auvDots = new HashMap<String, ArrayList<LatLng>>();
            Constants.auvColors = new HashMap<>();

            if (mAdapter != null) {
                UdpSocket.getInstance().sendMessage("INSTANTIMEI");
                return true;
            }

        } else if (menuItem.getItemId() == R.id.send_sail) {
            if (whichAnimation == 0) {
                /**
                 * Getting the center point of floating action button
                 *  to set start point of buttons
                 */
                startPositionX = 2600;
                startPositionY = 0;

                for (Button button : buttons) {
                    button.setX(startPositionX);
                    button.setY(startPositionY);
                    button.setVisibility(View.VISIBLE);
                }
                for (int i = 0; i < buttons.length; i++) {
                    playEnterAnimation(buttons[i], i);
                }
                whichAnimation = 1;
            } else {
                for (int i = 0; i < buttons.length; i++) {
                    playExitAnimation(buttons[i], i);
                }
                whichAnimation = 0;
            }
            return true;
        }
        return false;
    }

    /*
    private void createMarkerDialog() {
        alertDialog = new AlertDialog.Builder(SailTaskActivity.this)
                .setTitle("请输入该点处需要的航行参数")
                .setView(view)
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        alertDialog.dismiss();
                    }
                })
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String content1 = editTime.getText().toString();
                        String content2 = editSpeed.getText().toString();
                        String content3 = editDepth.getText().toString();

                        if (!content1.contentEquals("") && !content2.contentEquals("")
                                && !content3.contentEquals("")) {
                            if (mPosition != -1) {
                                mAdapter.modelList.get(mPosition).setSubText("afa,"//TODO afa
                                        + content1 + "," + content2 + "," + content3);
                                mRecyclerView.setAdapter(mAdapter);
                                mPosition = -1;
                            }
                        }

                        alertDialog.dismiss();
                    }
                }).create();
    }
    */

    private void createTestDialog() {
        headerDialog = new HeaderDialog(this);
        headerDialog.setColor(getResources().getColor(R.color.Control3)) // Sets the header background color
                .setElevation(false) // Sets the header elevation, true by default
                .setIcon(getResources().getDrawable(R.drawable.ic_content_paste_black_24dp)) // Sets the dialog icon image
                .setTitle(getResources().getString(R.string.addparameter)) // Sets the dialog title
                .setMessage("") // Sets the dialog message
                .justifyContent(true) // Justifies the message text, false by default
                .setTitleColor(Color.parseColor("#212121")) // Sets the header title text color
                .setIconColor(Color.parseColor("#212121")) // Sets the header icon color
                .setTitleGravity(Gravity.CENTER_HORIZONTAL) // Sets the header title text gravity
                .setMessageGravity(Gravity.CENTER_HORIZONTAL) // Sets the message text gravity
                .setTitleMultiline(false) // Multiline header title text option, true by default
                .setView(R.layout.sailtask_test_dialog) // Set custom view to the dialog (only possible via layout resource)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        EditText editParameter = headerDialog.getInflatedView().findViewById(R.id.input1);
                        String content1 = editParameter.getText().toString();

                        if (!content1.contentEquals("")) {
                            if (mPosition != -1) {
                                mAdapter.modelList.get(mPosition).setSubText("gps," + content1);
                                mRecyclerView.setAdapter(mAdapter);
                                mPosition = -1;
                            }
                        } else {
                            if (mPosition != -1) {
                                mAdapter.modelList.get(mPosition).setSubText("gps");
                                mRecyclerView.setAdapter(mAdapter);
                                mPosition = -1;
                            }
                        }
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                }).create();
    }

    private void createHeaderDialog() {
        String content = mAdapter.modelList.get(mPosition).getMainText();
        String information = null;
        if (content.contains("AUV")) {
            information = content.split(",")[0];
        } else {
            information = "请在下面添加AUV:" + mAdapter.modelList.get(mPosition).getMainText() + "的直航参数";
        }
        headerDialog = new HeaderDialog(this);
        headerDialog.setColor(getResources().getColor(R.color.Control3)) // Sets the header background color
                .setElevation(false) // Sets the header elevation, true by default
                .setIcon(getResources().getDrawable(R.drawable.ic_content_paste_black_24dp)) // Sets the dialog icon image
                .setTitle(getResources().getString(R.string.addparameter)) // Sets the dialog title
                .setMessage(information) // Sets the dialog message
                .justifyContent(true) // Justifies the message text, false by default
                .setTitleColor(Color.parseColor("#212121")) // Sets the header title text color
                .setIconColor(Color.parseColor("#212121")) // Sets the header icon color
                .setTitleGravity(Gravity.CENTER_HORIZONTAL) // Sets the header title text gravity
                .setMessageGravity(Gravity.CENTER_HORIZONTAL) // Sets the message text gravity
                .setTitleMultiline(false) // Multiline header title text option, true by default
                .setView(R.layout.sailtask_straight_dialog) // Set custom view to the dialog (only possible via layout resource)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        EditText editTime = headerDialog.getInflatedView().findViewById(R.id.input1);
                        EditText editSpeed = headerDialog.getInflatedView().findViewById(R.id.input2);
                        EditText editDepth = headerDialog.getInflatedView().findViewById(R.id.input3);
                        EditText editParameter = headerDialog.getInflatedView().findViewById(R.id.input4);
                        String content1 = editTime.getText().toString();
                        String content2 = editSpeed.getText().toString();
                        String content3 = editDepth.getText().toString();
                        String content4 = editParameter.getText().toString();

                        if (content4.contentEquals("")) {
                            content4 = "0.5,0.1,1.0,0.5,1";
                        }

                        if (!content1.contentEquals("") && !content2.contentEquals("")
                                && !content3.contentEquals("")) {
                            if (mPosition != -1) {
                                mAdapter.modelList.get(mPosition).setSubText("afa,"//TODO afa
                                        + content1 + "," + content2 + "," + content3 + "," + content4);
                                mRecyclerView.setAdapter(mAdapter);
                                mPosition = -1;
                            }
                        }
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                }).create();
    }
}
